function asyncCompose() {
  const func = [...arguments];
  return function (...args) {
    return func.reduce((prev, next) => {
      return Promise.resolve(prev).then((data) => next(data));
    }, ...args);
  };
}

function asyncComposes() {
  const func = [...arguments];

  return function (...args) {
    return func.reduce((prev, cur) => {
      console.log(prev, cur);
      return prev.then(cur);
    }, Promise.resolve(...args));
  };
}

const sub = (a) => {
  return new Promise((resolve, reject) => {
    resolve(a + 1);
  });
};

const sum = (a) => {
  return new Promise((resolve, reject) => {
    resolve(a + 12);
  });
};

const mul = (a) => {
  return new Promise((resolve, reject) => {
    resolve(a * 2);
  });
};

const addOne = asyncCompose(sub);
const addOneOne = asyncCompose(sum, sub);
const addOneTwo = asyncComposes(sum, sub);
// addOne(2).then((data) => {
//   console.log(data);
// });

// addOneOne(3).then((data) => {
//   console.log(data);
// });

addOneTwo(3).then((data) => {
  console.log(data);
});



function composeAsync() {
  const funs = [...arguments];

  return function (...args) {
    funs.reduce((prev, cur) => cur(prev), ...args);
  };
}